/*
 * Copyright (c) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * 日志级别枚举
 */
export enum LogLevel {
  DEBUG = 0,
  INFO = 1,
  WARN = 2,
  ERROR = 3,
  NONE = 4
}

/**
 * 日志配置接口
 */
export interface LoggerConfig {
  /** 最低显示的日志级别 */
  level: LogLevel;
  /** 是否使用颜色输出 */
  useColors: boolean;
  /** 是否显示时间戳 */
  showTimestamp: boolean;
  /** 是否显示日志来源 */
  showSource: boolean;
}

/**
 * 控制台颜色代码
 */
const COLORS = {
  reset: '\x1b[0m',
  bright: '\x1b[1m',
  dim: '\x1b[2m',
  underscore: '\x1b[4m',
  blink: '\x1b[5m',
  reverse: '\x1b[7m',
  hidden: '\x1b[8m',

  // 前景色
  fg: {
    black: '\x1b[30m',
    red: '\x1b[31m',
    green: '\x1b[32m',
    yellow: '\x1b[33m',
    blue: '\x1b[34m',
    magenta: '\x1b[35m',
    cyan: '\x1b[36m',
    white: '\x1b[37m',
    gray: '\x1b[90m',
  },

  // 背景色
  bg: {
    black: '\x1b[40m',
    red: '\x1b[41m',
    green: '\x1b[42m',
    yellow: '\x1b[43m',
    blue: '\x1b[44m',
    magenta: '\x1b[45m',
    cyan: '\x1b[46m',
    white: '\x1b[47m',
    gray: '\x1b[100m',
  }
};

/**
 * 日志级别对应的颜色和标签
 */
const LOG_LEVEL_CONFIG = {
  [LogLevel.DEBUG]: { color: COLORS.fg.gray, label: 'DEBUG' },
  [LogLevel.INFO]: { color: COLORS.fg.green, label: 'INFO' },
  [LogLevel.WARN]: { color: COLORS.fg.yellow, label: 'WARN' },
  [LogLevel.ERROR]: { color: COLORS.fg.red, label: 'ERROR' },
};

/**
 * 日志管理器类
 */
export class Logger {
  private static instance: Logger;
  private config: LoggerConfig = {
    level: LogLevel.INFO,
    useColors: true,
    showTimestamp: true,
    showSource: true
  };

  private constructor() {}

  /**
   * 获取Logger单例
   */
  public static getInstance(): Logger {
    if (!Logger.instance) {
      Logger.instance = new Logger();
    }
    return Logger.instance;
  }

  /**
   * 配置日志
   * @param config 日志配置
   */
  public configure(config: Partial<LoggerConfig>): void {
    this.config = { ...this.config, ...config };
  }

  /**
   * 输出调试级别日志
   * @param message 日志消息
   * @param source 日志来源
   */
  public debug(message: string, source: string = ''): void {
    this.log(LogLevel.DEBUG, message, source);
  }

  /**
   * 输出信息级别日志
   * @param message 日志消息
   * @param source 日志来源
   */
  public info(message: string, source: string = ''): void {
    this.log(LogLevel.INFO, message, source);
  }

  /**
   * 输出警告级别日志
   * @param message 日志消息
   * @param source 日志来源
   */
  public warn(message: string, source: string = ''): void {
    this.log(LogLevel.WARN, message, source);
  }

  /**
   * 输出错误级别日志
   * @param message 日志消息
   * @param source 日志来源
   */
  public error(message: string, source: string = ''): void {
    this.log(LogLevel.ERROR, message, source);
  }

  /**
   * 内部日志输出方法
   * @param level 日志级别
   * @param message 日志消息
   * @param source 日志来源
   */
  private log(level: LogLevel, message: string, source: string): void {
    // 检查日志级别是否应该被输出
    if (level < this.config.level) {
      return;
    }

    const levelConfig = LOG_LEVEL_CONFIG[level];
    const timestamp = this.config.showTimestamp ? `[${new Date().toISOString()}]` : '';
    const sourceStr = this.config.showSource && source ? `[${source}]` : '';
    const levelStr = `[${levelConfig.label}]`;
    
    let logMessage = '';
    
    if (this.config.useColors) {
      // 带颜色的日志
      logMessage = `${timestamp}${levelConfig.color}${levelStr}${COLORS.reset} ${sourceStr} ${message}`;
    } else {
      // 无颜色的日志
      logMessage = `${timestamp}${levelStr} ${sourceStr} ${message}`;
    }

    // 根据不同日志级别使用不同的控制台方法
    switch (level) {
      case LogLevel.DEBUG:
        console.debug(logMessage);
        break;
      case LogLevel.INFO:
        console.info(logMessage);
        break;
      case LogLevel.WARN:
        console.warn(logMessage);
        break;
      case LogLevel.ERROR:
        console.error(logMessage);
        break;
    }
  }
}

// 导出日志实例
export const logger = Logger.getInstance(); 